<?php
/**
 * Zend Framework Contribution
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Mwb
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    1.0 Table.php 3 mai 2012 Sergio DE VASCONCELOS
 */

require_once('Zend/Mwb/Dom/Abstract.php');
require_once('Zend/Mwb/Dom/Columns.php');
require_once('Zend/Mwb/Dom/ForeignKeys.php');

/**
 * MySQL Workbench document
 *
 * @category   Zend
 * @package    Zend_Mwb
 */
class Zend_Mwb_Dom_Table extends Zend_Mwb_Dom_Abstract
{
	public static $defaultNamespace = 'Application_Model_';
	public static $defaultExtendedClass = 'Zend_Db_Table_Abstract';
	
	protected $class;
	public $dependentTables;
	protected $referenceMap;
	
	protected $name;
	/**
	 * @var Zend_Mwb_Dom_Columns
	 */
	protected $columns;
	/**
	 * @var Zend_Mwb_Dom_ForeignKeys
	 */
	protected $foreignKeys;
	/**
	 * @var Zend_Mwb_Dom_Indices
	 */
	protected $indices;
	
	
	public function getClass() {
		if (is_null($this->class)) {
			$camelCase = new Zend_Filter_Word_UnderscoreToCamelCase();
			$this->class = $camelCase->filter($this->name);
		}
		return $this->class;
	}
	
	
	public function getName() {
		if (is_null($this->name)) {
			$this->name = $this->loadName();
		}
		return $this->name;
	}
	
	public function setName($name) { }
	public function getColumns() {
		if (is_null($this->columns)) {
			$this->columns = $this->loadColumns();
		}
		return $this->columns;
	}
	public function setColumns($name) { }
	//public function addCollumn($column) { }
	
	public function getForeignKeys() {
		if (is_null($this->foreignKeys)) {
			$this->foreignKeys = $this->loadForeignKeys();
		}
		return $this->foreignKeys;
	}
	public function setForeignKeys($name) { }
	//public function addForeignKeys() { }
	
	public function getIndices() {
		if (is_null($this->indices)) {
			$this->indices = $this->loadIndices();
		}
		return $this->indices;
	}
	public function setIndices($indices) { }
	//public function addForeignKeys() { }
	public function hasPrimary() {
		foreach($this->getIndices() as $indice) {
			if ($indice->getType() == 'PRIMARY') {
				//$this->primary[] = $indice->getOwner()->getName();
				return true;
			}
		}
		return false;
	}
	public function getPrimary() {
		$this->primary = array();
		//<link type="object" struct-name="db.mysql.Index" key="primaryKey">9fe39d62-9bc6-11e1-af0e-5404a6bea04e</link>
		foreach($this->getIndices() as $indice) {
			if ($indice->getType() == 'PRIMARY') {
				// if FK continue;
				foreach ($indice->getIndexColumns() as $indexColumn) {
					$this->primary[] = $indexColumn->getReferencedColumn();
				}
			}
		}
		return $this->primary;
	}
	
	public function getDependentTables() {
		if (is_null($this->dependentTables)) {
			$this->dependentTables = array();
			foreach ($this->parent as $table) {
				$table->getReferenceMap();
			}
			$this->parent->rewind();
		}
		return $this->dependentTables;
	}
	public function addDependentTable($table) {
		$this->dependentTables = empty($this->dependentTables) ? array() : $this->dependentTables;
		if (!in_array($table, $this->dependentTables, true))
			$this->dependentTables[] = $table;
		return $this;
	}
	
	public function getReferenceMap() {
		if(is_null($this->referenceMap)) {
			$this->referenceMap = array();
			$foreignKeys = $this->getForeignKeys();
			foreach ($foreignKeys as $foreignKey) {
				$columns       = $foreignKey->getColumns();
				$refTable      = $foreignKey->getReferencedTable();
				$refColumns    = $foreignKey->getReferencedColumns();
				$role = ucfirst(current($columns)->getName());// TODO use Filter
				
				$this->referenceMap[$role] = array(
					'columns'    => current($columns)->getName(),// array_map($columns, array($obj, 'getName'))
					'refTable'   => self::$defaultNamespace . $refTable->getClass(),
					'refColumns' => current($refColumns)->getName(),
				);
				$refTable->addDependentTable($this);
			}
		}
		return $this->referenceMap;
	}
	
	public function parse() {
		$this->xpath = new DOMXPath($this->node->ownerDocument);
		
		$this->name        = $this->loadName();
		$this->columns     = $this->loadColumns();
		$this->foreignKeys = $this->loadForeignKeys();
		$this->indices     = $this->loadIndices();
	}
	/**
	 * @param DOMElement $dom
	 * @return 
	 */
	protected function loadName() {
    	$element = $this->xpath->query("value[@key='name']", $this->node)->item(0);
    	if (isset($element)) {
        	return $element->textContent;
        } else {
        	require_once 'Zend/Mwb/Exception.php';
        	throw new Zend_Mwb_Exception('Dom_Exception_Null($this->node)');
        }
	}
	/**
	 * @param String $name
	 * @param DOMElement $dom
	 * @return 
	 */
	protected function saveName($name, DOMElement $dom=null) {
    	$element = $this->xpath->query("value[@key='name']", $this->node)->item(0);
        if (isset($element)) {
        	$element->textContent = $name;
        }// FIXME else create/lazyload
	}
	
	/**
	 * @param DOMElement $dom
	 * @return Zend_Mwb_Dom_Columns
	 */
	protected function loadColumns() {
    	$elements = $this->xpath->query("value[@key='columns']/value", $this->node);
    	return new Zend_Mwb_Dom_Columns($elements, $this);
	}
	/**
	 * @param DOMElement $dom
	 * @return Zend_Mwb_Dom_ForeignKeys
	 */
	protected function loadForeignKeys() {
    	$elements = $this->xpath->query("value[@key='foreignKeys']/value", $this->node);
    	return new Zend_Mwb_Dom_ForeignKeys($elements, $this);
	}
	/**
	 * @param DOMElement $dom
	 * @return Zend_Mwb_Dom_Indices
	 */
	protected function loadIndices() {
    	$elements = $this->xpath->query("value[@key='indices']/value", $this->node);
    	return new Zend_Mwb_Dom_Indices($elements, $this);
	}
	
	public function create() {
		
$xml = <<<XXX
                <value type="object" struct-name="db.mysql.Table" id="{D1F6E044-B27A-4136-A250-0C5866B2F630}" struct-checksum="0x1a403946">
                  <value type="string" key="avgRowLength"></value>
                  <value type="int" key="checksum">0</value>
                  <value _ptr_="0x5e017a0" type="list" content-type="object" content-struct-name="db.mysql.Column" key="columns">
                  
                  </value>
                  <value type="string" key="connectionString"></value>
                  <value type="string" key="defaultCharacterSetName">utf8</value>
                  <value type="string" key="defaultCollationName"></value>
                  <value type="int" key="delayKeyWrite">0</value>
                  <value _ptr_="0x5e01830" type="list" content-type="object" content-struct-name="db.mysql.ForeignKey" key="foreignKeys" />
                  <value _ptr_="0x5e018c0" type="list" content-type="object" content-struct-name="db.mysql.Index" key="indices">
                  <value type="string" key="maxRows"></value>
                  <value type="string" key="mergeInsert"></value>
                  <value type="string" key="mergeUnion"></value>
                  <value type="string" key="minRows"></value>
                  <value type="string" key="nextAutoInc"></value>
                  <value type="string" key="packKeys"></value>
                  <value type="int" key="partitionCount">0</value>
                  <value _ptr_="0x5e019f0" type="list" content-type="object" content-struct-name="db.mysql.PartitionDefinition" key="partitionDefinitions"/>
                  <value type="string" key="partitionExpression"></value>
                  <value type="string" key="partitionType"></value>
                  <value type="string" key="password"></value>
                  <link type="object" struct-name="db.mysql.Index" key="primaryKey">{1232F014-58EB-4BD5-AB58-F6EBD01C5BAE}</link>
                  <value type="string" key="raidChunkSize"></value>
                  <value type="string" key="raidChunks"></value>
                  <value type="string" key="raidType"></value>
                  <value type="string" key="rowFormat"></value>
                  <value type="int" key="subpartitionCount">0</value>
                  <value type="string" key="subpartitionExpression"></value>
                  <value type="string" key="subpartitionType"></value>
                  <value type="string" key="tableDataDir"></value>
                  <value type="string" key="tableEngine">MyISAM</value>
                  <value type="string" key="tableIndexDir"></value>
                  <value _ptr_="0x5e01950" type="list" content-type="object" content-struct-name="db.mysql.Trigger" key="triggers"/>
                  <value type="int" key="isStub">0</value>
                  <value type="int" key="isSystem">0</value>
                  <value type="int" key="isTemporary">0</value>
                  <value type="string" key="temporaryScope"></value>
                  <value type="int" key="commentedOut">0</value>
                  <value type="string" key="createDate">2008-10-29 11:22</value>
                  <value _ptr_="0x5e01420" type="dict" key="customData"/>
                  <value type="string" key="lastChangeDate">2008-10-29 11:22</value>
                  <value type="int" key="modelOnly">0</value>
                  <value type="string" key="name">access</value>
                  <value type="string" key="temp_sql"></value>
                  <value type="string" key="comment"></value>
                  <value type="string" key="oldName">access</value>
                  <link type="object" struct-name="GrtObject" key="owner">{747E97A7-B86F-4233-8EDC-E02644B9551B}</link>
                </value>
XXX;
		
	}
}
